package com.brainhealth.customer.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.brainhealth.common.constant.Constants;
import com.brainhealth.common.constant.NextChatFlagConstants;
import com.brainhealth.common.constant.NumberConstants;
import com.brainhealth.common.enums.*;
import com.brainhealth.common.utils.DateUtils;
import com.brainhealth.common.utils.NumberUtils;
import com.brainhealth.customer.domain.*;
import com.brainhealth.customer.domain.vo.ChatAiVO;
import com.brainhealth.customer.service.*;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ChatIDService {
    /**
     * 日志
     */
    Logger logger = LoggerFactory.getLogger(ChatIDService.class);

    /**
     * 订单
     */
    @Autowired
    private IExerciseOrderService exerciseOrderService;

    /**
     * 会员训练记录
     */
    @Autowired
    private ICustomerExerciseService customerExerciseService;

    @Autowired
    private IExerciseService exerciseService;

    @Autowired
    private IChatRecordService chatRecordService;

    @Autowired
    private IChatMainService chatMainService;

    @Autowired
    private IAIChatService aiChatService;

    public void handChatId(ChatQueryParam chatQueryParam, Customer customer, List<ChatTemplate> chatList,ChatBase chatBase) {
        List<CustomerExercise> notFinishedCustomerExerciseList=chatBase.getNotFinishedCustomerExerciseList();
        List<CustomerExercise> finishedCustomerExerciseList =chatBase.getFinishedCustomerExerciseList();
        List<CustomerExercise> expiredCustomerExerciseList = chatBase.getExpiredCustomerExerciseList();
        ExerciseOrder exerciseOrderParam = new ExerciseOrder();
        exerciseOrderParam.setStatus(PayStatus.Exercise);
        ExerciseOrder exerciseOrder = exerciseOrderService.getCustomerExerciseOrder(customer, exerciseOrderParam);
        if (null == exerciseOrder) {
            logger.warn("用户ID{}昵称{} 训练中的订单为空", customer.getCustomerId(), customer.getNickName());
            exerciseOrderParam.setStatus(PayStatus.Finish);
            exerciseOrder = exerciseOrderService.getCustomerExerciseOrder(customer, exerciseOrderParam);
        }

        ChatMain chatMain = new ChatMain();
        chatMain.setOrderNo(exerciseOrder.getOrderId());
        chatMain.setCustomerId(customer.getCustomerId());
        List<ChatMain> chatMainList = chatMainService.selectChatMainList(chatMain);
        if (CollectionUtils.isNotEmpty(chatMainList)
            && chatMainList.get(0).getCourseNo() < customer.getCountSort()
        ){
            // -> 造成DATE循环发送问题
            logger.info("处理聊天记录ID主表课程编号{}用户表课程编号{}", chatMainList.get(0).getCourseNo(), customer.getCountSort());
            chatQueryParam.setChatId(NextChatFlagConstants.DATE);
        }

        String nextChatFlag = chatQueryParam.getChatId();
        switch (nextChatFlag) {
            case NextChatFlagConstants.BASE: {
                int chatId = getBaseChatId(chatList);
                chatQueryParam.setLongChatId(Long.valueOf(chatId));
            }
            break;
            case NextChatFlagConstants.DATE: {
                int chatId = getDateChatId(chatList);
                chatQueryParam.setLongChatId(Long.valueOf(chatId));
            }
            break;
            case NextChatFlagConstants.COMPLETED:
            case NextChatFlagConstants.REMIND: {
                int chatId = getProgressChatId(customer, chatList, nextChatFlag,notFinishedCustomerExerciseList,finishedCustomerExerciseList,expiredCustomerExerciseList);
                chatQueryParam.setLongChatId(Long.valueOf(chatId));
            }
            break;
            case NextChatFlagConstants.REPORT: {
                int reportChatId = getReportChatId(chatQueryParam, chatList);
                chatQueryParam.setLongChatId(Long.valueOf(reportChatId));
            }
            break;
            case NextChatFlagConstants.AFTER_REPORT: {
                int reportChatId = getAfterReportChatId(customer, chatList);
                chatQueryParam.setLongChatId(Long.valueOf(reportChatId));
            }
            break;
            case NextChatFlagConstants.KNOWLEDGE:
            case NextChatFlagConstants.RETURN_KNOWLEDGE: {
                int knowledgeChatId = getKnowledgeChatId(chatList);
                chatQueryParam.setLongChatId(Long.valueOf(knowledgeChatId));
            }
            break;
            case NextChatFlagConstants.RETURN_BEGIN: {
                int exerciseStatus = getExerciseStatus(customer);
                int returnBeginChatId = getBeginChatId(exerciseStatus, chatQueryParam,chatList);
                chatQueryParam.setLongChatId(Long.valueOf(returnBeginChatId));
            }
            break;
            case NextChatFlagConstants.CHAT_NEXT: {
                // 如果当次 -> 不聊了
                // 如果返回 -> RETURN_BEGIN
                Integer courseNo = chatQueryParam.getCourseNo();
                int iCountSort = customer.getCountSort().intValue();
                if (courseNo == iCountSort) {
                    int chatId=getChatEndChatId(chatList);
                    chatQueryParam.setLongChatId(Long.valueOf(chatId));
                    break;
                }
                int chatId = getDateChatId(chatList);
                chatQueryParam.setLongChatId(Long.valueOf(chatId));
            }
            break;
            case NextChatFlagConstants.RETURN_BASE:{
                String chatId = getReturnBaseChatId(chatQueryParam, customer,chatList);
                chatQueryParam.setLongChatId(Long.valueOf(chatId));
            }
            break;
            case NextChatFlagConstants.RETURN_END: {
                // -> 继续聊: 当前课程未结束，当前聊天未结束
                // -> CHAT_END：当前课程已结束，当前聊天已结束，下次课程未开启
                // -> DATE：当前课程已结束：当前聊天已开启，下次课程已开启
                String chatId = getReturnEndChatId( chatQueryParam, customer,chatList,chatBase);
                chatQueryParam.setLongChatId(Long.valueOf(chatId));
            }
            break;
            case NextChatFlagConstants.AFTER_ASK_MOOD: {
                Long chatId = getAfterAskMoodChatId(customer,chatList);
                chatQueryParam.setLongChatId(chatId);
            }
            break;
            default:
                chatQueryParam.setLongChatId(Long.valueOf(chatQueryParam.getChatId()));
                break;
        }
    }

    /**
     * 查询课程状态
     *
     * @param customer
     * @return
     */
    public int getExerciseStatus(Customer customer) {
        ExerciseOrder exerciseOrderParam = new ExerciseOrder();
        exerciseOrderParam.setStatus(PayStatus.Exercise);
        ExerciseOrder exerciseOrder = exerciseOrderService.getCustomerExerciseOrder(customer, exerciseOrderParam);
        if (null==exerciseOrder){
            exerciseOrderParam.setStatus(PayStatus.Finish);
            exerciseOrder=exerciseOrderService.getCustomerExerciseOrder(customer,exerciseOrderParam);
        }
        CustomerExercise customerExercise = new CustomerExercise();
        customerExercise.setOrderId(exerciseOrder.getOrderId());
        customerExercise.setCustomerId(customer.getCustomerId());
        customerExercise.setCountSort(customer.getCountSort());
        List<CustomerExercise> customerExerciseList = customerExerciseService.selectCustomerExerciseList(customerExercise);
        customerExercise.setStatus(CustomerExerciseStatus.Finished);
        List<CustomerExercise> finishCustomerExerciseList = customerExerciseService.selectCustomerExerciseList(customerExercise);
        if (CollectionUtils.isEmpty(finishCustomerExerciseList)) {
            return ExerciseStatusEnum.ZERO.getCode();
        }
        if (!CollectionUtils.isEmpty(customerExerciseList) && finishCustomerExerciseList.size() == customerExerciseList.size()) {
            return ExerciseStatusEnum.OVER.getCode();
        }
        return ExerciseStatusEnum.HALF.getCode();
    }

    /**
     * 获取聊天模板ID
     * 适用于基础信息
     *
     * @param chatList
     * @return
     */
    public int getBaseChatId(List<ChatTemplate> chatList) {
        final int chatCategory1Id = ChatCategoryEnum.BASE.getCategory1Code();
        chatList = chatList.stream().filter(item -> item.getChatCategory1Id().equals(chatCategory1Id)).collect(Collectors.toList());
        ChatTemplate chatTemplate = getChatIdTemplateByIndex(chatList, NumberConstants.ZERO);
        int chatId = chatTemplate.getChatId().intValue();
        return chatId;
    }

    public int getChatEndChatId(List<ChatTemplate> chatList) {
        final int chatCategory1Id = ChatCategoryEnum.CHAT_END.getCategory1Code();
        chatList = chatList.stream().filter(item -> item.getChatCategory1Id().equals(chatCategory1Id)).collect(Collectors.toList());
        ChatTemplate chatTemplate = getChatIdTemplateByIndex(chatList, NumberConstants.ZERO);
        int chatId = chatTemplate.getChatId().intValue();
        return chatId;
    }

    /**
     * 获取聊天模板ID
     * 适用于日期打招呼
     *
     * @param chatList
     * @return
     */
    public int getDateChatId(List<ChatTemplate> chatList) {
        final int chatCategory1Id = ChatCategoryEnum.DATE.getCategory1Code();
        LocalDateTime now = LocalDateTime.now();
        DayOfWeek dayOfWeek = now.getDayOfWeek();
        int value = dayOfWeek.getValue();
        final int chatCategory2Id = value;
        chatList = chatList.stream().filter(item -> item.getChatCategory1Id().equals(chatCategory1Id) && null!= item.getChatCategory2Id() &&item.getChatCategory2Id().equals(chatCategory2Id)).collect(Collectors.toList());
        ChatTemplate chatTemplate = getChatIdTemplateByIndex(chatList, NumberConstants.ZERO);
        int chatId = chatTemplate.getChatId().intValue();
        return chatId;
    }

    public String getReturnBaseChatId(ChatQueryParam chatQueryParam,Customer customer, List<ChatTemplate> chatList) {
        //RETURN_END 前一条主逻辑
        //用ChatId+CourseNo 比较，判断是否当前课程，是否聊天已结束
        //用OpenTime判断下次课程已开启

        // 继续聊: 当前课程未结束，当前聊天未结束
        // CHAT_END：当前课程已结束，当前聊天已结束，下次课程未开启
        // DATE：当前课程已结束：当前聊天未结束，下次课程已开启
        ExerciseOrder exerciseOrderParam = new ExerciseOrder();
        exerciseOrderParam.setStatus(PayStatus.Exercise);
        ExerciseOrder exerciseOrder = exerciseOrderService.getCustomerExerciseOrder(customer, exerciseOrderParam);
        ChatRecord chatRecord = new ChatRecord();
        chatRecord.setOrderNo(exerciseOrder.getOrderId());
        chatRecord.setCustomerId(customer.getCustomerId());
        chatRecord.setChatType(ChatContentTypeEnum.MAIN.getCode());
        ChatRecord mainChatRecord = chatRecordService.selectChatRecord(chatRecord);
        //未开始
        if (null == chatRecord) {
            logger.warn("用户：{}，订单：{}，课程：{}，当前无聊天主逻辑", customer.getCustomerId(), exerciseOrder.getOrderId(), customer.getCountSort());
        }

        String nextChatFlag = mainChatRecord.getNextChatFlag();
        if (!NumberUtils.isNumeric(nextChatFlag) && NextChatFlagConstants.DATE.equals(nextChatFlag) ){
            int dateChatId = getDateChatId(chatList);
            chatQueryParam.setChatId(String.valueOf(dateChatId));
            chatQueryParam.setAnswerType(mainChatRecord.getAnswerType());
            return chatQueryParam.getChatId();
        }

        chatQueryParam.setChatId(nextChatFlag);
        chatQueryParam.setAnswerType(mainChatRecord.getAnswerType());
        return mainChatRecord.getNextChatFlag();
    }

    public String getReturnEndChatId(ChatQueryParam chatQueryParam,Customer customer,List<ChatTemplate> chatList,ChatBase chatBase)
    {
        // RETURN_END 前一条主逻辑
        // 用ChatId+CourseNo 比较，判断是否当前课程，是否聊天已结束
        // 用OpenTime判断下次课程已开启

        // 继续聊: 当前课程未结束，当前聊天未结束
        // CHAT_END：当前课程已结束，当前聊天已结束，下次课程未开启
        // DATE：当前课程已结束：当前聊天未结束，下次课程已开启
        ExerciseOrder exerciseOrder = exerciseOrderService.getExerciseOrder(customer);
        ChatRecord chatRecord = new ChatRecord();
        chatRecord.setOrderNo(exerciseOrder.getOrderId());
        chatRecord.setCustomerId(customer.getCustomerId());
        chatRecord.setChatType(ChatContentTypeEnum.MAIN.getCode());
        //chatRecord.setNextChatFlag(NextChatFlagConstants.CHAT_NEXT);
        ChatRecord mainChatRecord = chatRecordService.selectChatRecord(chatRecord);
        //未开始
        if (null==mainChatRecord){
            logger.warn("用户：{}，订单：{}，课程：{}，当前无聊天主逻辑",customer.getCustomerId(),exerciseOrder.getOrderId(),customer.getCountSort());
            return NextChatFlagConstants.DATE;
        }
        chatRecord.setChatType(null);
        ChatRecord returnChatRecord = chatRecordService.selectChatRecord(chatRecord);
        //未开始
        if (null==returnChatRecord || !NextChatFlagConstants.RETURN_END.equals(returnChatRecord.getNextChatFlag())){
            logger.warn("用户：{}，订单：{}，课程：{}，当前聊天最后一条不是RETURN_END",customer.getCustomerId(),exerciseOrder.getOrderId(),customer.getCountSort());
        }

        boolean currentChatStatus = false;
        if (null != mainChatRecord && null != mainChatRecord.getNextChatFlag()) {
            currentChatStatus = NextChatFlagConstants.CHAT_NEXT.equals(mainChatRecord.getNextChatFlag());
        }

        //当前课程未完成 & 当前聊天未完成 -> 接着聊
        //当前课程已完成 & 当前聊天未完成 -> 接着聊

        //当前聊天未完成-> 接着聊
        if (!currentChatStatus){
            //更多菜单/每日报告/7日报告/28日报告/续费卡片
            if(InputTypeEnum.MORE_FUNC.getCode().equals(mainChatRecord.getInputType())
                    || InputTypeEnum.REPORT_CARD_DAY.getCode().equals(mainChatRecord.getInputType())
                    || InputTypeEnum.REPORT_CARD_SEVEN.getCode().equals(mainChatRecord.getInputType())
                    || InputTypeEnum.REPORT_CARD_TWENTY_EIGHT.getCode().equals(mainChatRecord.getInputType())
                    || InputTypeEnum.RENEW_CARD.getCode().equals(mainChatRecord.getInputType())){
                chatQueryParam.setChatId(mainChatRecord.getChatFlag());
                chatQueryParam.setAnswerType(mainChatRecord.getAnswerType());
                return mainChatRecord.getChatFlag();
            }

            if(InputTypeEnum.ERNIE_BOT.getCode().equals(mainChatRecord.getInputType())){
                ChatAiTokens chatAiTokens = new ChatAiTokens();
                BeanUtils.copyProperties(chatBase,chatAiTokens);
                ChatAiVO chatAiVO = aiChatService.getChatAiVO(chatAiTokens);
                if (null == chatAiVO || null == chatAiVO.getTotalTokens()) {
                    logger.warn("获取文心一言聊天统计结果异常");
                    chatAiVO.setTotalTokens(0l);
                }

                Integer answerType = mainChatRecord.getAnswerType();
                //如果选择的是 "开始训练"
                if (AnswerTypeEnum.RIGHT.getCode()==answerType){
                    chatQueryParam.setAnswerType(AnswerTypeEnum.RIGHT.getCode());
                    return mainChatRecord.getNextChatFlag();
                }

                //如果选择的是 "继续聊天"
                if (AnswerTypeEnum.CONTINUE_CHAT.getCode()==answerType) {
                    //走"开始训练"逻辑
                    if (chatAiVO.getTotalTokens() > NumberConstants.TWO_THOUSAND) {
                        chatQueryParam.setAnswerType(AnswerTypeEnum.RIGHT.getCode());
                        return mainChatRecord.getNextChatFlag();
                    }
                    //走"继续聊天"逻辑，再次询问"开始训练||继续聊天"   inputType  + answerType + chatEntrance(category1Code)
                    String content = mainChatRecord.getContent();
                    ChatContent chatContent = JSON.toJavaObject(JSONObject.parseObject(content), ChatContent.class);
                    Integer chatEntrance = chatContent.getChatEntrance();
                    Integer chatCategory = getChatCategoryCodeByChatEntrance(chatEntrance);
                    final int chatCategory1Id = chatCategory;
                    chatList = chatList.stream().filter(item -> item.getInputType().equals(InputTypeEnum.ERNIE_BOT.getCode()))
                            .filter(item -> item.getChatCategory1Id().equals(chatCategory1Id))
                            .collect(Collectors.toList());
                    ChatTemplate chatTemplate = getChatIdTemplateByIndex(chatList, NumberConstants.ZERO);
                    int chatId = chatTemplate.getChatId().intValue();
                    return String.valueOf(chatId);
                }
            }

            String nextChatFlag = mainChatRecord.getNextChatFlag();
            if (!NumberUtils.isNumeric(nextChatFlag)){
                chatQueryParam.setChatId(nextChatFlag);
                handChatId(chatQueryParam,customer,chatList,chatBase);

                chatQueryParam.setChatId(String.valueOf(chatQueryParam.getLongChatId()));
                chatQueryParam.setAnswerType(mainChatRecord.getAnswerType());
                return chatQueryParam.getChatId();
            }
            //TODO: AnswerType 测试
            chatQueryParam.setChatId(mainChatRecord.getNextChatFlag());
            chatQueryParam.setAnswerType(mainChatRecord.getAnswerType());
            return mainChatRecord.getNextChatFlag();
        }

        //当前课程已完成 & 当前聊天已完成 & 下次课程未开启-> CHAT_END
        // nextExerciseStatus=!nextExerciseStatus;
        // if (currentExerciseStatus && currentChatStatus && nextExerciseStatus){
        //     int chatId=chatIDService.getChatEndChatId(chatList);
        //     return String.valueOf(chatId);
        // }
        //nextExerciseStatus=!nextExerciseStatus;

        //if (currentExerciseStatus && currentChatStatus){
        //    int chatId= getChatEndChatId(chatList);
        //    return String.valueOf(chatId);
        //}

        //当前聊天已完成-> CHAT_END
        if (currentChatStatus){
            int chatId= getChatEndChatId(chatList);
            return String.valueOf(chatId);
        }

        return returnChatRecord.getNextChatFlag();
    }

    private Integer getChatCategoryCodeByChatEntrance(Integer chatEntrance) {
        if (null == chatEntrance) {
            return null;
        }
        if (ErnieBotEntranceEnum.ENTRANCE_1_BEFORE_EXERCISE.getCode().equals(chatEntrance)) {
            return ChatCategoryEnum.ENTER_EXERCISE.getCategory1Code();
        }
        if (ErnieBotEntranceEnum.ENTRANCE_2_AFTER_EXERCISE.getCode().equals(chatEntrance)) {
            return ChatCategoryEnum.MORE_FUNC.getCategory1Code();
        }
        if (ErnieBotEntranceEnum.ENTRANCE_3_ASK_MOOD.getCode().equals(chatEntrance)) {
            return ChatCategoryEnum.ERNIE_BOT_ENTRANCE.getCategory1Code();
        }
        return null;
    }


    private Long getAfterAskMoodChatId(Customer customer, List<ChatTemplate> chatTemplateList) {
        ChatAiTokens chatAiTokens = new ChatAiTokens();
        chatAiTokens.setCustomerId(customer.getCustomerId());
        String orderNo = exerciseOrderService.getOrderNo(customer);
        chatAiTokens.setOrderNo(orderNo);
        chatAiTokens.setCourseNo(customer.getCountSort());
        ChatAiVO ernieBotChat = aiChatService.getChatAiVO(chatAiTokens);
        if (
                (null != ernieBotChat &&
                        null != ernieBotChat.getCount() &&
                        null != ernieBotChat.getTotalTokens()) &&
                        (ernieBotChat.getCount() > NumberConstants.ONE
                                || ernieBotChat.getTotalTokens() > NumberConstants.TWO_THOUSAND)
        ) {
            //超过2000字或聊过2次 -> 告知陪伴
            Integer category1Code = ChatCategoryEnum.TELL_COMPANY.getCategory1Code();
            chatTemplateList = chatTemplateList.stream().filter(item -> item.getChatCategory1Id() == category1Code).collect(Collectors.toList());
            ChatTemplate chatTemplate = chatTemplateList.get(0);

            return chatTemplate.getChatId();
        }
        //未超过2000字且未超过2次 -> 文心一言入口3
        Integer category1Code = ChatCategoryEnum.ERNIE_BOT_ENTRANCE.getCategory1Code();
        chatTemplateList = chatTemplateList.stream().filter(item -> item.getChatCategory1Id() == category1Code).collect(Collectors.toList());
        ChatTemplate chatTemplate = chatTemplateList.get(0);

        return chatTemplate.getChatId();
    }

    /**
     * 获取聊天模板ID
     * 已训练次数和剩余训练次数告知
     *
     * @param chatList
     * @return
     */
    public int getProgressChatId(Customer customer, List<ChatTemplate> chatList, String nextChatFlag,List<CustomerExercise> notFinishedCustomerExerciseList,List<CustomerExercise> finishedCustomerExerciseList,List<CustomerExercise> expiredCustomerExerciseList) {

        //未完成为空&&完成为空 -> 异常
        if (CollectionUtils.isEmpty(notFinishedCustomerExerciseList) && CollectionUtils.isEmpty(finishedCustomerExerciseList) && CollectionUtils.isEmpty(expiredCustomerExerciseList)) {
            return -1;
        }
        //完成为空 -> 未开始
        if (CollectionUtils.isEmpty(finishedCustomerExerciseList)&&CollectionUtils.isEmpty(expiredCustomerExerciseList)) {
            final int enterExercise = ChatCategoryEnum.ENTER_EXERCISE.getCategory1Code();
            chatList = chatList.stream().filter(item -> item.getChatCategory1Id().equals(enterExercise)).collect(Collectors.toList());
            ChatTemplate chatTemplate = getChatIdTemplateByIndex(chatList, NumberConstants.ZERO);
            int chatId = chatTemplate.getChatId().intValue();
            return chatId;
        }
        //全部完成，未完成为空 -> 完成
        if (CollectionUtils.isEmpty(notFinishedCustomerExerciseList) && exerciseService.getCompletedState(finishedCustomerExerciseList,expiredCustomerExerciseList)) {
            OptionalLong optionalLong = finishedCustomerExerciseList.stream().mapToLong(CustomerExercise::getCountSort).max();
            Long courNo = optionalLong.getAsLong();
            chatList = getChatTemplateList(chatList, courNo, nextChatFlag);
            ChatTemplate chatTemplate = getChatIdTemplateByIndex(chatList, NumberConstants.ZERO);
            if (nextChatFlag.equals(NextChatFlagConstants.REMIND)){
                chatTemplate = getChatIdTemplateByIndex(chatList, NumberConstants.ONE);
            }
            int chatId = chatTemplate.getChatId().intValue();
            return chatId;
        }

        OptionalLong optionalLong = notFinishedCustomerExerciseList.stream().mapToLong(CustomerExercise::getCountSort).min();
        Long courNo = optionalLong.getAsLong();
        chatList = getChatTemplateList(chatList, courNo, nextChatFlag);
        ChatTemplate chatTemplate = getChatIdTemplateByIndex(chatList, NumberConstants.ZERO);
        int chatId = chatTemplate.getChatId().intValue();
        return chatId;
    }

    private List<ChatTemplate> getChatTemplateList(List<ChatTemplate> chatList,Long courseNo, String nextChatFlag)
    {
        //中间过程
        final int chatCategory1Id = ChatCategoryEnum.REMIND_COMPLETED.getCategory1Code();
        final int chatCategory2Id = nextChatFlag.equals(NextChatFlagConstants.COMPLETED) ? ChatCategoryEnum.REMIND_COMPLETED.getCategory2Code() : ChatCategoryEnum.REMIND_REMIND.getCategory2Code();
        Map<Integer, Integer> map = nextChatFlag.equals(NextChatFlagConstants.COMPLETED) ? ProgressNotifyEnum.getCompletedMap() : ProgressNotifyEnum.getRemindMap();
        Integer code = map.get(courseNo.intValue());
        if (null == code) {
            //进入训练主题
            final int enterExercise = ChatCategoryEnum.ENTER_EXERCISE.getCategory1Code();
            chatList = chatList.stream().filter(item -> item.getChatCategory1Id().equals(enterExercise)).collect(Collectors.toList());
        } else {
            final int chatCategory3Id = code;
            chatList = chatList.stream().filter(item -> item.getChatCategory1Id().equals(chatCategory1Id) && item.getChatCategory2Id().equals(chatCategory2Id) && item.getChatCategory3Id().equals(chatCategory3Id)).collect(Collectors.toList());
        }
        return chatList;
    }

    public int getReportChatId(ChatQueryParam chatQueryParam, List<ChatTemplate> chatTemplateList) {
        int courseNo = chatQueryParam.getCourseNo();
        int chatCategory1Id = ChatCategoryEnum.REPORT_1.getCategory1Code();
        int chatCategory2Id = ChatCategoryEnum.REPORT_1.getCategory2Code();
        if (courseNo == Constants.TIME_7) {
            chatCategory1Id = ChatCategoryEnum.REPORT_7.getCategory1Code();
            chatCategory2Id = ChatCategoryEnum.REPORT_7.getCategory2Code();
        }
        if (courseNo == Constants.TIME_28) {
            chatCategory1Id = ChatCategoryEnum.REPORT_28.getCategory1Code();
            chatCategory2Id = ChatCategoryEnum.REPORT_28.getCategory2Code();
        }
        final int category1Id = chatCategory1Id;
        final int category2Id = chatCategory2Id;
        chatTemplateList = chatTemplateList.stream().filter(item -> item.getChatCategory1Id().equals(category1Id) && item.getChatCategory2Id().equals(category2Id)).collect(Collectors.toList());
        ChatTemplate chatTemplate = getChatIdTemplateByIndex(chatTemplateList, NumberConstants.ZERO);
        int chatId = chatTemplate.getChatId().intValue();
        return chatId;
    }

    public int getAfterReportChatId(Customer customer, List<ChatTemplate> chatTemplateList) {
        if (null != customer.getMechanismId()
                && UserTypeEnum.EXPERIENCE_USER.getCode().equals(customer.getMechanismId())
        ){
            boolean payFlag = getIsNotPay(customer);
            if( (customer.getCountSort() == NumberConstants.THREE || customer.getCountSort()== NumberConstants.FIVE) && payFlag ){
                //体验用户续费提醒
                int category1Code = ChatCategoryEnum.RENEW_EXPERIENCE_COURSE.getCategory1Code();
                int category2Code = ChatCategoryEnum.RENEW_EXPERIENCE_COURSE.getCategory2Code();
                int chatId = getChatId(chatTemplateList, category1Code, category2Code);
                return chatId;
            }else{
                int category1Code = ChatCategoryEnum.OVER_TIPS.getCategory1Code();
                int chatId = getChatId(chatTemplateList, category1Code, -1);
                return chatId;
            }
        }

        Map<String, Long> progressMap =  customerExerciseService.getProgressMap(customer);
        int reminds = progressMap.get(Constants.MARK_REMIND_DAYS).intValue();

        boolean payFlag = getIsNotPay(customer);

        if (reminds == Constants.REMINDS_7 && payFlag) {

            //判断是否已续费
            int category1Code = ChatCategoryEnum.RENEW_7.getCategory1Code();
            int category2Code = ChatCategoryEnum.RENEW_7.getCategory2Code();
            int chatId = getChatId(chatTemplateList, category1Code, category2Code);
            return chatId;
        }

        if (reminds == Constants.REMINDS_3 && payFlag) {

            //判断是否已续费
            int category1Code = ChatCategoryEnum.RENEW_3.getCategory1Code();
            int category2Code = ChatCategoryEnum.RENEW_3.getCategory2Code();
            int chatId = getChatId(chatTemplateList, category1Code, category2Code);
            return chatId;
        }

        if (reminds == Constants.REMINDS_0 && payFlag) {
            //判断是否已续费
            int category1Code = ChatCategoryEnum.RENEW_0.getCategory1Code();
            int category2Code = ChatCategoryEnum.RENEW_0.getCategory2Code();
            int chatId = getChatId(chatTemplateList, category1Code, category2Code);
            return chatId;
        }

        int category1Code = ChatCategoryEnum.OVER_TIPS.getCategory1Code();
        int chatId = getChatId(chatTemplateList, category1Code, -1);
        return chatId;
    }

    public int getKnowledgeChatId(List<ChatTemplate> chatTemplateList) {
        Integer category1Code = ChatCategoryEnum.KNOWLEDGE_CONTENT.getCategory1Code();
        Integer category2Code = ChatCategoryEnum.KNOWLEDGE_CONTENT.getCategory2Code();
        chatTemplateList = chatTemplateList.stream()
                .filter(item -> item.getChatCategory1Id().equals(category1Code))
                .filter(item -> item.getChatCategory2Id().equals(category2Code))
                .collect(Collectors.toList());
        ChatTemplate chatTemplate = getChatIdTemplateByIndex(chatTemplateList, NumberConstants.ZERO);
        int chatId = chatTemplate.getChatId().intValue();
        return chatId;
    }

    public int getBeginChatId(int exerciseStatus, ChatQueryParam queryParam, List<ChatTemplate> chatTemplateList) {
        Integer category1Code = ChatCategoryEnum.RETURN_OVER.getCategory1Code();
        Integer category2Code = ChatCategoryEnum.RETURN_OVER.getCategory2Code();
        if (ExerciseStatusEnum.ZERO.getCode() == exerciseStatus) {
            category1Code = ChatCategoryEnum.RETURN_ZERO.getCategory1Code();
            category2Code = ChatCategoryEnum.RETURN_ZERO.getCategory2Code();
        }
        if (ExerciseStatusEnum.HALF.getCode() == exerciseStatus) {
            category1Code = ChatCategoryEnum.RETURN_HALF.getCategory1Code();
            category2Code = ChatCategoryEnum.RETURN_HALF.getCategory2Code();
        }
        if (ExerciseStatusEnum.OVER.getCode() == exerciseStatus) {
            category1Code = ChatCategoryEnum.RETURN_OVER.getCategory1Code();
            category2Code = ChatCategoryEnum.RETURN_OVER.getCategory2Code();
            queryParam.setCourseStatus(ExerciseStatusEnum.OVER.getCode());
        }
        final int returnCategory1Code = category1Code;
        final int returnCategory2Code = category2Code;
        chatTemplateList = chatTemplateList.stream()
                .filter(item -> item.getChatCategory1Id().equals(returnCategory1Code))
                .filter(item -> item.getChatCategory2Id().equals(returnCategory2Code))
                .collect(Collectors.toList());
        ChatTemplate chatTemplate = getChatIdTemplateByIndex(chatTemplateList, NumberConstants.ZERO);
        int chatId = chatTemplate.getChatId().intValue();
        return chatId;
    }

    public int getBeginChatId(int exerciseStatus, ChatQueryParam queryParam, Customer customer,List<ChatTemplate> chatTemplateList,List<CustomerExercise> finishedCustomerExerciseList,List<CustomerExercise> notFinishCustomerExerciseList) {
        ExerciseOrder exerciseOrderParam = new ExerciseOrder();
        exerciseOrderParam.setStatus(PayStatus.Exercise);
        ExerciseOrder exerciseOrder = exerciseOrderService.getCustomerExerciseOrder(customer, exerciseOrderParam);
        ChatRecord chatRecord = new ChatRecord();
        chatRecord.setOrderNo(exerciseOrder.getOrderId());
        chatRecord.setCustomerId(customer.getCustomerId());
        chatRecord.setChatType(ChatContentTypeEnum.MAIN.getCode());
        ChatRecord mainChatRecord = chatRecordService.selectChatRecord(chatRecord);
        int i = mainChatRecord.getCourseNo().intValue() + 1;
        CustomerExercise customerExercise = new CustomerExercise();
        customerExercise.setCustomerId(customer.getCustomerId());
        customerExercise.setOrderId(exerciseOrder.getOrderId());
        customerExercise.setCountSort(Long.valueOf(i));

        //List<CustomerExercise> finishedCustomerExerciseList=customerExerciseService.getCustomerExerciseList(customer, CustomerExerciseStatus.Finished);
        //当前课程是否完成
        //boolean currentExerciseStatus = finishedCustomerExerciseList.size()==NumberConstants.TWO;
        List<CustomerExercise> nextCustomerExerciseList = customerExerciseService.selectCustomerExerciseList(customerExercise);

        //下一课程是否开启 - 当前未完成的课程
        boolean nextExerciseStatus= getExerciseStatus(notFinishCustomerExerciseList);
        //下一课程已开启（不论当前课程是否结束，当前聊天是否结束）
        if (mainChatRecord.getCourseNo()!=notFinishCustomerExerciseList.get(0).getCountSort() && nextExerciseStatus){
            int dateChatId = getDateChatId(chatTemplateList);
            return dateChatId;
        }

        Integer category1Code = ChatCategoryEnum.RETURN_OVER.getCategory1Code();
        Integer category2Code = ChatCategoryEnum.RETURN_OVER.getCategory2Code();
        if (ExerciseStatusEnum.ZERO.getCode() == exerciseStatus) {
            category1Code = ChatCategoryEnum.RETURN_ZERO.getCategory1Code();
            category2Code = ChatCategoryEnum.RETURN_ZERO.getCategory2Code();
        }
        if (ExerciseStatusEnum.HALF.getCode() == exerciseStatus) {
            category1Code = ChatCategoryEnum.RETURN_HALF.getCategory1Code();
            category2Code = ChatCategoryEnum.RETURN_HALF.getCategory2Code();
        }
        if (ExerciseStatusEnum.OVER.getCode() == exerciseStatus) {
            category1Code = ChatCategoryEnum.RETURN_OVER.getCategory1Code();
            category2Code = ChatCategoryEnum.RETURN_OVER.getCategory2Code();
            queryParam.setCourseStatus(ExerciseStatusEnum.OVER.getCode());
        }
        final int returnCategory1Code = category1Code;
        final int returnCategory2Code = category2Code;
        chatTemplateList = chatTemplateList.stream()
                .filter(item -> item.getChatCategory1Id().equals(returnCategory1Code))
                .filter(item -> item.getChatCategory2Id().equals(returnCategory2Code))
                .collect(Collectors.toList());
        ChatTemplate chatTemplate = getChatIdTemplateByIndex(chatTemplateList, NumberConstants.ZERO);
        int chatId = chatTemplate.getChatId().intValue();
        return chatId;
    }

    /**
     * 下节课程开启状态 false:未开启 true:已开启
     * @param notFinishCustomerExerciseList
     * @return
     */
    public boolean getExerciseStatus(List<CustomerExercise> notFinishCustomerExerciseList)
    {
        //普通用户
        if (CollectionUtils.isEmpty(notFinishCustomerExerciseList)) {
            return false;
        }

        boolean nextExerciseStatus = false;
        for (CustomerExercise exercise : notFinishCustomerExerciseList) {
            if (!DateUtils.compare(new Date(), exercise.getOpenTime())) {
                nextExerciseStatus = false;
                break;
            }
            nextExerciseStatus = true;
        }
        return nextExerciseStatus;
    }

    private boolean getIsNotPay(Customer customer) {
        ExerciseOrder order = new ExerciseOrder();
        order.setCustomerId(customer.getCustomerId());
        order.setStatus(PayStatus.Paid);
        List<ExerciseOrder> exerciseOrderList = exerciseOrderService.selectExerciseOrderList(order);
        return CollectionUtils.isEmpty(exerciseOrderList) ? true : false;
    }


    private int getChatId(List<ChatTemplate> chatTemplateList, int category1Id, int category2Id) {
        if (-1 != category1Id & -1 == category2Id) {
            chatTemplateList = chatTemplateList.stream().filter(item -> item.getChatCategory1Id().equals(category1Id)).collect(Collectors.toList());
            ChatTemplate chatTemplate = getChatIdTemplateByIndex(chatTemplateList, NumberConstants.ZERO);
            int chatId = chatTemplate.getChatId().intValue();
            return chatId;
        }

        if (-1 != category1Id && -1 != category2Id) {
            chatTemplateList = chatTemplateList.stream().filter(item -> item.getChatCategory1Id().equals(category1Id) && item.getChatCategory2Id().equals(category2Id)).collect(Collectors.toList());
            ChatTemplate chatTemplate = getChatIdTemplateByIndex(chatTemplateList, NumberConstants.ZERO);
            int chatId = chatTemplate.getChatId().intValue();
            return chatId;
        }
        return -1;
    }

    private ChatTemplate getChatIdTemplateByIndex(List<ChatTemplate> collect, int index) {
        if (index==NumberConstants.ZERO){
            OptionalLong min = collect.stream().mapToLong(ChatTemplate::getChatId).min();
            List<ChatTemplate> collect1 = collect.stream().filter(item -> item.getChatId() == min.getAsLong()).collect(Collectors.toList());
            ChatTemplate chatTemplate = collect1.get(NumberConstants.ZERO);
            return chatTemplate;
        }
        if (index==NumberConstants.ONE){
            List<ChatTemplate> collect1 =collect.stream().sorted(Comparator.comparing(ChatTemplate::getId)).collect(Collectors.toList());
            ChatTemplate chatTemplate = collect1.get(NumberConstants.ONE);
            return chatTemplate;
        }
        return null;
    }

}
